import asyncio
import os
import time
from datetime import datetime

from conf.const import RedisConst, EnvConst
from extensions import logger
from services.redis_ext import redis_op


class CacheOp:

    @staticmethod
    async def verify_api_secret(value: str):
        """校验 API secret"""
        if os.environ.get('CODE_ENV', EnvConst.TEST) == EnvConst.DEV:
            name = f'{EnvConst.DEV}:{RedisConst.ApiSecret.Name}'
        else:
            name = f'{RedisConst.ApiSecret.Name}'
        # name = f'{RedisConst.ApiSecret.Name}'
        result = await redis_op.get(name=name)
        logger.info(result)

        return result == value

    @classmethod
    async def get_gemini_api_allow(cls, model_name: str, limit: int):
        """Get GeminiAllow"""

        return await cls.get_lock(
            name=f'{model_name}:apiAllow', lock_name=f'{model_name}:apiAllowLock',
            expiry=RedisConst.GeminiAPIAllow.Expiry, lock_expiry=RedisConst.GeminiAPIAllowLock.Expiry,
            limit=limit
        )

    @classmethod
    async def get_gemini_count_allow(cls, model_name: str, limit: int):
        """Get GeminiCountAllow"""

        return await cls.get_lock(
            name=f'{model_name}:countAllow', lock_name=f'{model_name}:countAllowLock',
            expiry=RedisConst.GeminiCountAllow.Expiry, lock_expiry=RedisConst.GeminiCountAllowLock.Expiry,
            limit=limit
        )

    @staticmethod
    async def get_lock(name: str, lock_name: str, expiry: int, lock_expiry: int, limit: int):

        is_success = False
        start_time = time.time()
        while time.time() - start_time < lock_expiry:
            now = datetime.now().strftime('%Y-%m-%d-%H-%M')
            _used_name, _lock_name = f'{name}:{now}', f'{lock_name}:{now}'

            success, _ = await redis_op.get_lock(name=_lock_name, timeout=lock_expiry)
            if not success:
                await asyncio.sleep(2)
                continue

            value = await redis_op.get(name=_used_name)
            if not value:
                await redis_op.increasing(name=_used_name, value=1, expiry=expiry)
                is_success = True
            else:
                if int(value) >= limit:
                    await asyncio.sleep(2)
                    continue
                else:
                    await redis_op.increasing(name=_used_name, value=1, expiry=expiry)
                    is_success = True

            # 删除锁
            await redis_op.delete(name=_lock_name)
            return is_success

        return is_success

    @staticmethod
    async def delete(name: str):
        """删除"""

        await redis_op.delete(name=name)
